package com.qire.manhua.model.viewModel.impl;

import android.app.Activity;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;

import com.qire.antscore.annotation.PropertyObserve;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.basic.StringUtil;
import com.qire.common.model.entity.UserEntity;
import com.qire.common.support.base.BaseViewModel;
import com.qire.common.utils.CountDownTimerBuilder;
import com.qire.common.utils.ToastHelper;
import com.qire.manhua.R;
import com.qire.manhua.dal.service.AccountsAssociatedAddService;
import com.qire.manhua.databinding.ActivityAccountsAssociatedAddBinding;
import com.qire.manhua.model.viewModel.IAccountsAssociatedAddViewModel;

import net.yslibrary.android.keyboardvisibilityevent.util.UIUtil;

import java.util.concurrent.TimeUnit;


public class AccountsAssociatedAddViewModel extends BaseViewModel<IAccountsAssociatedAddViewModel> {

    private AccountsAssociatedAddService addService = new AccountsAssociatedAddService(this);

    private int pageNo = 0;

    private int associatedUserId;
    private String associatedUserPortrait;
    private String associatedUserName;
    private String associatedUserHash;
    private String addUsedValidateCode = "";

    private ActivityAccountsAssociatedAddBinding viewDataBinder;

    //region    #附加管理 begin

    /**
     * 附加属性绑定
     * @param activity
     * @param viewDataBinder 页面数据绑定器
     */
    public void onAddition(Activity activity, ActivityAccountsAssociatedAddBinding viewDataBinder) {
        this.viewDataBinder = viewDataBinder;
    }

    /**
     * 清理函数，在Activity退出时，ViewModel生命周期到期会被回收，调用该事件，
     * 页面由于切换、横竖屏转换、内存回收等情况并不会影响到ViewModel的生命周期。
     */
    @Override
    protected void onCleared() {
        super.onCleared();
        addService = null;
        viewDataBinder = null;
    }
    //endregion #附加管理 end

    //region    #业务及数据 begin
    public void fetchVerifyCode() {
        startCountDown();
        requestVerifyCode1Focus();

        String phoneNumber = phoneNumber();
        if(StringUtil.notEmpty(phoneNumber)) {
            addService.fetchVerifyCode(phoneNumber);
        } else {
            ToastHelper.showToast("未输入手机号码");
        }
    }

    public void checkVerificationCode() {
        if(!verifyCodeIsValid()) {
            ToastHelper.showToast("无效的验证码");
            return;
        }
        addService.checkVerificationCode(phoneNumber(), verifyCode());
    }

    /** 设置添加操作时使用的接口验证码 */
    public void setAddUsedValidateCode(String addUsedValidateCode) {
        this.addUsedValidateCode = addUsedValidateCode;
    }

    public void accountVerifyByPhone() {
        addService.accountVerifyByPhone(phoneNumber());
    }
    public void accountVerifyByWeChat() {
        addService.accountVerifyByWeChat();
    }
    public void accountVerifyByQQ() {
        addService.accountVerifyByQQ();
    }

    /** 设置验证后的关联账户信息 */
    public void setAssociatedUserInfo(int userId, String userPortrait, String userName, String userHash) {
        this.associatedUserId = userId;
        this.associatedUserPortrait = userPortrait;
        this.associatedUserName = userName;
        this.associatedUserHash = userHash;
        refreshAccountsInfo();
    }

    public void accountsAssociatedAdd() {
        addService.accountAssociatedAdd(associatedUserId, associatedUserHash, addUsedValidateCode);
    }
    //endregion #业务及数据 end

    //region    #面板操作 begin

    /**
     * 返回上一个面板，如果是顶层结束面板则直接返回 true；
     * @return 如果当前面板不是顶层结束面板则返回false，否则返回true。
     */
    public boolean backPanel() {
        boolean isFinish = pageNo <= 0;
        if(!isFinish) {
            gotoPanel(0);
        }
        return isFinish;
    }

    /**
     * 跳转到指定页面面板号
     */
    public void gotoPanel(int pageNo) {
        this.pageNo = pageNo;
        int wizardPanel         = pageNo == 0 ? View.VISIBLE : View.GONE;
        int phonePanel          = pageNo == 1 ? View.VISIBLE : View.GONE;
        int validateCodePanel   = pageNo == 2 ? View.VISIBLE : View.GONE;
        int thirdPanel          = pageNo == 3 ? View.VISIBLE : View.GONE;
        int ResultPanel         = pageNo == 4 ? View.VISIBLE : View.GONE;
        set("panelVisible", new int[] {wizardPanel, phonePanel, validateCodePanel, thirdPanel, ResultPanel});
    }

    //endregion #面板操作 end

    //region    #手机号关联 begin

    private String phoneNumber() {
        return getToValue("phoneNumber");
    }

    @PropertyObserve(name = "phoneNumber")
    public void onPhoneNumberChange(String phoneNumber) {
        boolean phoneIsValid = (!TextUtils.isEmpty(phoneNumber)) && StringUtil.isMobile(phoneNumber);
        set("phoneVerifyButtonEnabled", phoneIsValid);
        set("phoneVerifyButtonTextColor", phoneIsValid ? "#423300" : "#aeaeae");
        set("phoneVerifyButtonBackground", phoneIsValid ? R.drawable.app_accounts_associated_bg_yellow : R.drawable.app_accounts_associated_bg_gray);
    }

    //endregion #手机号关联 end

    //region    #验证码 begin
    private int verifyCode1 = -1;
    private int verifyCode2 = -1;
    private int verifyCode3 = -1;
    private int verifyCode4 = -1;

    /** 验证码计时器*/
    private CountDownTimer timer;

    public void requestVerifyCode1Focus() {
        final EditText focusView = viewDataBinder.verifyCode1;
        focusView.requestFocus();
        focusView.postDelayed(()-> UIUtil.showKeyboard(focusView.getContext(), focusView), 300);
    }

    /** 获取验证码倒计时*/
    private void startCountDown() {
        if(ObjectUtil.nonNull(timer)) {
            timer.cancel();
            timer.onFinish();
        }

        setFetchVerifyCodeTextEnabled(false);
        timer = CountDownTimerBuilder.build(60, 1, TimeUnit.SECONDS)
                .addTickCallBack((countDownTime, timeUnit) -> {
                    setFetchVerifyCodeText(String.format("重新获取(%ss)", countDownTime--));
                    return countDownTime;
                })
                .addFinishCallBack((countDownTime, timeUnit) -> {
                    resetGetCodeButton();
                    return countDownTime;
                }).start();
    }
    /** 恢复获取验证码按钮*/
    private void resetGetCodeButton() {
        timer.cancel();
        setFetchVerifyCodeText("重新获取");
        setFetchVerifyCodeTextEnabled(true);
    }

    private void setFetchVerifyCodeText(CharSequence fetchVerifyCodeText) {
        set("fetchVerifyCodeText", fetchVerifyCodeText);
    }

    private void setFetchVerifyCodeTextEnabled(boolean fetchVerifyCodeTextEnabled) {
        set("fetchVerifyCodeTextColor", fetchVerifyCodeTextEnabled ? "#ff9204" : "#aeaeae");
        set("fetchVerifyCodeTextEnabled", fetchVerifyCodeTextEnabled);
    }

    private String verifyCode() {
        return String.format("%s%s%s%s", verifyCode1, verifyCode2, verifyCode3, verifyCode4);
    }

    private boolean verifyCodeIsValid() {
        return verifyCode1 >= 0 && verifyCode2 >= 0 && verifyCode3 >= 0 && verifyCode4 >= 0;
    }


    /**
     * 刷新验证码确认按钮状态
     */
    private void refreshVerifyBtn() {
        put("verifyBtnEnabled", verifyCodeIsValid());
        put("verifyBtnTextColor", verifyCodeIsValid() ? "#423300" : "#aeaeae");
        put("verifyBtnBackground", verifyCodeIsValid() ? R.drawable.app_accounts_associated_bg_yellow : R.drawable.app_accounts_associated_bg_gray);
    }

    /**
     * 以下是4个验证码输入框的状态监听，如果输入框内容发生改变则会触发观察者消息
     */
    @PropertyObserve(name = "verifyCode1")
    public void setVerifyCode1(String verifyCode1) {
        try {
            int codeValue = Integer.valueOf(verifyCode1);
            // 解决光标位置问题导致可能最新输入的字符在旧字符前需要判断故做一下数值运算处理，始终使用最新值替换旧值；
            if(codeValue != this.verifyCode1) {
                this.verifyCode1 = codeValue % 10 == this.verifyCode1 ? codeValue / 10 : codeValue % 10;
            }
            viewDataBinder.verifyCode2.requestFocus();
        } catch(Exception e) {
            this.verifyCode1 = -1;
        }
        refreshVerifyBtn();
    }
    @PropertyObserve(name = "verifyCode2")
    public void setVerifyCode2(String verifyCode2) {
        try {
            int codeValue = Integer.valueOf(verifyCode2);
            if(codeValue != this.verifyCode2) {
                this.verifyCode2 = codeValue % 10 == this.verifyCode2 ? codeValue / 10 : codeValue % 10;
            }
            viewDataBinder.verifyCode3.requestFocus();
        } catch(Exception e) {
            this.verifyCode2 = -1;
            viewDataBinder.verifyCode1.requestFocus();
        }
        refreshVerifyBtn();
    }
    @PropertyObserve(name = "verifyCode3")
    public void setVerifyCode3(String verifyCode3) {
        try {
            int codeValue = Integer.valueOf(verifyCode3);
            if(codeValue != this.verifyCode3) {
                this.verifyCode3 = codeValue % 10 == this.verifyCode3 ? codeValue / 10 : codeValue % 10;
            }
            viewDataBinder.verifyCode4.requestFocus();
        } catch(Exception e) {
            this.verifyCode3 = -1;
            viewDataBinder.verifyCode2.requestFocus();
        }
        refreshVerifyBtn();
    }
    @PropertyObserve(name = "verifyCode4")
    public void setVerifyCode4(String verifyCode4) {
        try {
            int codeValue = Integer.valueOf(verifyCode4);
            if(codeValue != this.verifyCode4) {
                this.verifyCode4 = codeValue % 10 == this.verifyCode4 ? codeValue / 10 : codeValue % 10;
            }
        } catch(Exception e) {
            this.verifyCode4 = -1;
            viewDataBinder.verifyCode3.requestFocus();
        }
        refreshVerifyBtn();
    }
    //endregion #验证码 end

    //region    #关联账号信息 begin

    public void refreshAccountsInfo() {
        set("currentUserHeadImage", UserEntity.self.getPortrait());
        set("currentUserName", UserEntity.self.getName());
        set("currentUserID", "ID: " + UserEntity.self.getId());
        set("associatedUserHeadImage", this.associatedUserPortrait);
        set("associatedUserName", this.associatedUserName);
        set("associatedUserID", "ID: " + this.associatedUserId);
    }

    //endregion #关联账号信息 end

    //region    #业务及数据 begin
    //endregion #业务及数据 end

    //region    #关联结果 begin
    public void showResultPanel(boolean isSuccess, String resultTips) {
        set("resultIcon", isSuccess ? R.drawable.app_accounts_associated_icon_success : R.drawable.app_accounts_associated_icon_relation_fail);
        set("resultText", isSuccess ? "关联成功" : "关联失败");
        set("resultTips", resultTips);
        gotoPanel(4);
    }
    //endregion #关联结果 end

}
